package com.yqtsoft.utils.excel.core;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 常用 抽象方法实现
 *
 * @author: CrazyShaQiuShi
 * @email: 3105334046@qq.com
 * @date: 2018-11-25 12:51
 * @version: 1.0
 */
public abstract class AbstractExcelUtil<T> extends AbstractExcel<T> {
    static final Logger LOG = LoggerFactory.getLogger(AbstractExcelUtil.class);
    /**
     * 旧文件格式
     */
    private final static String XLS = "xls";
    /**
     * 新文件格式
     */
    private final static String XLSX = "xlsx";

    @Override
    public List<T> importExcel(String sheetName, File file) throws Exception {
        if (null == file) {
            LOG.error("文件不存在！");
            throw new FileNotFoundException("文件不存在！");
        }
        //获得文件名
        String fileName = file.getName();
        //判断文件是否是excel文件
        if (!fileName.endsWith(XLS) && !fileName.endsWith(XLSX)) {
            LOG.error(fileName + "不是excel文件");
            throw new IOException(fileName + "不是excel文件");
        }
        if (fileName.endsWith(XLS)) {
            //根据文件名称
            return importXLSFile(sheetName, new FileInputStream(file));
        } else {
            return importXLSXFile(sheetName, new FileInputStream(file));
        }
    }

    @Override
    public List<T> importExcel(String fileName, InputStream inputStream) throws IOException {
        //判断文件是否是excel文件
        if (!fileName.endsWith(XLS) && !fileName.endsWith(XLSX)) {
            LOG.error(fileName + "不是excel文件");
            throw new IOException(fileName + "不是excel文件");
        }
        if (fileName.endsWith(XLS)) {
            //根据文件名称
            return importXLSFile(null, inputStream);
        } else {
            return importXLSXFile(null, inputStream);
        }
    }

    @Override
    public List<T> importExcel(String fileName, String sheetName, InputStream inputStream) throws IOException {
        //判断文件是否是excel文件
        if (!fileName.endsWith(XLS) && !fileName.endsWith(XLSX)) {
            LOG.error(fileName + "不是excel文件");
            throw new IOException(fileName + "不是excel文件");
        }
        if (fileName.endsWith(XLS)) {
            //根据文件名称
            return importXLSFile(sheetName, inputStream);
        } else {
            return importXLSXFile(sheetName, inputStream);
        }
    }

    /**
     * xls格式支持
     *
     * @param sheetName
     * @param input
     * @return
     */
    public List<T> importXLSFile(String sheetName, InputStream input) {
        List<T> list = null;
        try {
            HSSFWorkbook workbook = new HSSFWorkbook(input);
            HSSFSheet sheet =null;
            if (!StringUtils.isEmpty(sheetName)) {
                //如果指定sheet名,则取指定sheet中的内容.
                sheet = workbook.getSheet(sheetName);
            }
            if (sheet == null) {
                //如果传入的sheet名不存在则默认指向第1个sheet.
                sheet = workbook.getSheetAt(0);
            }
            list = dispatch(sheet);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 对xlsx格式的支持
     *
     * @param sheetName
     * @param input
     * @return
     */
    public List<T> importXLSXFile(String sheetName, InputStream input) {
        List<T> list = null;
        try {
            XSSFWorkbook workbook = new XSSFWorkbook(input);
            XSSFSheet sheet=null;
            if (!StringUtils.isEmpty(sheetName)) {
                //如果指定sheet名,则取指定sheet中的内容.
                sheet = workbook.getSheet(sheetName);
            }
            if (sheet == null) {
                //如果传入的sheet名不存在则默认指向第1个sheet.
                sheet = workbook.getSheetAt(0);
            }
            list = dispatch(sheet);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }


    @Override
    public boolean exportExcel(List<T> list, String sheetName, OutputStream output) {
        //此处 对类型进行转换
        List<T> ilist = new ArrayList<>();
        for (T t : list) {
            ilist.add(t);
        }
        List<T>[] lists = new ArrayList[1];
        lists[0] = ilist;

        String[] sheetNames = new String[1];
        sheetNames[0] = sheetName;
        return exportExcel(lists, sheetNames, output);
    }

    @Override
    public boolean exportExcel(List<T>[] lists, String[] sheetNames, OutputStream output) {
        if (lists.length != sheetNames.length) {
            System.out.println("数组长度不一致");
            return false;
        }

        // 创建excel工作簿
        HSSFWorkbook wb = ExcelTool.createWorkbook();
        // 创建第一个sheet（页），命名为 new sheet
        for (int ii = 0; ii < lists.length; ii++) {
            List<T> list = lists[ii];
            // 产生工作表对象
            HSSFSheet sheet = ExcelTool.createSheet(ii, sheetNames[ii]);
            // 创建表头
            createHeader(wb, sheet);
            // 写入数据
            int rowStart = 1;
            for (T t : list) {
                createRow(t, sheet);
                rowStart = mergedRegio(t, sheet, rowStart);
            }

        }
        try {
            output.flush();
            wb.write(output);
            output.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Output is closed ");
            return false;
        }

    }

}
